Amazon DynamoDB Local で新たに2つの DynamoDB API をサポートしました
こんにちは、森田です。
以下のアップデートで Amazon DynamoDB Local にて新しい DynamoDB API を利用することができるようになりました。
今回新たにサポートされたAPIは以下の通りです。
- deletion protection(削除保護)
- ReturnValuesOnConditionCheckFailure(条件付き書き込み失敗時のレスポンス設定)
これら2つの機能は、DynamoDBで2023年に発表されたものですが、今まで DynamoDB Local では対応しておらず、テストを行うことができませんでした。
今回のアップデートで、これらのAPIに対しても対応できるようになったため、DynamoDB Local でも動作テストができるようになります。
やってみた
では、実際に Dynamo DB Local を利用して新しいAPIを叩いてみます。
DynamoDB Local の起動
本記事では、dynamodb-local イメージを利用して DynamoDB Local をコンテナ上で起動させます。
docker pull amazon/dynamodb-local docker run -d --name dynamodb-local -p 8000:8000 amazon/dynamodb-local
削除保護
今回は、boto3を利用してAPIを叩いてみます。
削除保護を有効にしてテーブルの作成
以下のコードを実行して、テーブルの作成を行います。
DynamoDB Local を利用するために、endpoint_urlを指定します。
import boto3 # DynamoDBリソースを作成し、エンドポイントURLを指定します。 dynamodb = boto3.resource('dynamodb', endpoint_url='http://localhost:8000/') # テーブルを作成するためのパラメータを設定します。 table_name = 'User' attribute_definitions = [ { 'AttributeName': 'userId', 'AttributeType': 'S' } ] key_schema = [ { 'AttributeName': 'userId', 'KeyType': 'HASH' } ] provisioned_throughput = { 'ReadCapacityUnits': 5, 'WriteCapacityUnits': 5 } # テーブルを作成します。 table = dynamodb.create_table( TableName=table_name, AttributeDefinitions=attribute_definitions, KeySchema=key_schema, ProvisionedThroughput=provisioned_throughput, DeletionProtectionEnabled=True #削除保護 ) # テーブルの作成が完了するまで待ちます。 table.meta.client.get_waiter('table_exists').wait(TableName=table_name) print(f"Table {table_name} has been created.")
$ python3 create.py Table User has been created.
削除保護を有効にしたテーブルの削除
以下のコードを実行しても、削除することができず、エラーが発生します。
import boto3 table_name = "User" # DynamoDBクライアントを作成します。 dynamodb = boto3.client('dynamodb', endpoint_url='http://localhost:8000/') dynamodb.delete_table(TableName=table_name)
$ python3 delete.py botocore.exceptions.ClientError: An error occurred (ValidationException) when calling the DeleteTable operation: Resource cannot be deleted as it is currently protected against deletion. Disable deletion protection first.
削除保護を無効後、テーブルの削除
では、削除できるように、削除保護を無効化して、テーブルの削除を行います。
import boto3 table_name = "User" # DynamoDBクライアントを作成します。 dynamodb = boto3.client('dynamodb', endpoint_url='http://localhost:8000/') # 削除保護を無効化 response = dynamodb.update_table( TableName=table_name, DeletionProtectionEnabled=False #削除保護 ) dynamodb.delete_table(TableName=table_name)
$ python3 delete2.py
今度はエラーなく実行ができ、テーブルの削除が行えます。
ReturnValuesOnConditionCheckFailure
今回は以下の記事のコードを参考に動作検証を行います。
テーブル作成とアイテムの追加
以下のコードで動作確認用のテーブル作成とアイテム追加を行います。
import boto3 dynamodb = boto3.client("dynamodb", endpoint_url='http://localhost:8000/') table_name = "sample_table" response = dynamodb.create_table( TableName=table_name, KeySchema=[{"AttributeName": "id", "KeyType": "HASH"}], AttributeDefinitions=[{"AttributeName": "id", "AttributeType": "N"}], BillingMode="PAY_PER_REQUEST", ) dynamodb.get_waiter("table_exists").wait(TableName=table_name) print("テーブル 作成成功") item = { "id": {"N": "1"}, "name": {"S": "yamada taro"}, "email": {"S": "[email protected]"}, } dynamodb.put_item( TableName=table_name, Item=item, ) print("アイテム 作成成功")
$ python3 item_create.py テーブル 作成成功 アイテム 作成成功
条件付き書き込み
続いて以下のコードを実行して、条件付き書き込みを行います。
idが存在しない場合に書き込みが成功する指定を行っていますが、先ほどid=1のアイテムを追加しているためエラーとなります。
import boto3 from botocore.exceptions import ClientError dynamodb = boto3.client("dynamodb", endpoint_url='http://localhost:8000/') table_name = "sample_table" # idのみが同一のitem item = { "id": {"N": "1"}, "name": {"S": "satou hanako"}, "email": {"S": "[email protected]"}, } try: dynamodb.put_item( TableName=table_name, Item=item, ConditionExpression="attribute_not_exists(id)", # idが存在しない場合にのみ書き込み ReturnValuesOnConditionCheckFailure="ALL_OLD", ) print("Item 追加成功") except ClientError as e: if e.response["Error"]["Code"] == "ConditionalCheckFailedException": print(e.response.get("Item"))
$ python3 put.py {'name': {'S': 'yamada taro'}, 'email': {'S': '[email protected]'}, 'id': {'N': '1'}}
実行結果からも、期待した通りに、元のアイテムをエラー時に返却しています。
さいごに
今回新しいAPIにも対応したため、ますます DynamoDB Local が使いやすくなりました。
DynamoDB をテスト用で利用したい場合には、 DynamoDB Local は非常に便利なツールですので、ぜひチェックしてみてください!